import axios, { AxiosError } from 'axios';
import { ref } from 'vue';

// --- 配置 ---
const API_SERVER = '';
const API_BASE_URL = `${API_SERVER}/api/auth`;

// --- TypeScript 接口 ---

// 用户接口
export interface User {
  id: number;
  email: string | null;
  phone_number: string | null;
  is_admin?: boolean;
  email_verified?: boolean;
  phone_verified?: boolean;
}

interface AuthResponse {
  message: string;
  user?: User; // 可选，因为并非所有响应都包含完整的用户对象
}

// Registration
interface RegisterPayload {
  email?: string;
  phone_number?: string;
  password?: string;
}

// 使用密码登录
interface LoginPasswordPayload {
  identifier: string; // email or phone number
  password?: string;
  remember_me?: boolean;
}

// 发送OTP
interface SendOtpPayload {
  phone_number: string;
}

// 验证OTP
interface VerifyOtpPayload {
  phone_number: string;
  otp: string;
}

// 忘记密码请求
interface ForgotPasswordRequestPayload {
  identifier: string; // email or phone number
}

// 使用Token重置密码
interface ResetPasswordTokenPayload {
  token: string;
  new_password?: string;
}

// 通用错误响应（根据你的Flask错误结构调整）
interface ApiErrorResponse {
  error: string;
  // You might have other fields like 'details' or 'code'
}

// --- 响应式状态（可选 - 用于演示目的） ---
const currentUser = ref<User | null>(null);
const isLoading = ref(false);
const errorMessage = ref<string | null>(null); // 错误信息

// --- API Service Functions ---

/**
 * 处理API错误，提取用户友好的错误信息。
 * @param error 来自Axios（或其他来源）的错误对象。
 * @param defaultMessage 如果无法提取特定信息时的默认消息。
 * @returns 用户友好的错误信息字符串。
 */
const handleApiError = (error: any, defaultMessage: string = 'An unexpected error occurred.'): string => {
  if (axios.isAxiosError(error)) {
    const axiosError = error as AxiosError<ApiErrorResponse>;
    if (axiosError.response && axiosError.response.data && axiosError.response.data.error) {
      return axiosError.response.data.error;
    }
    return axiosError.message;
  }
  if (error instanceof Error) {
    return error.message;
  }
  return defaultMessage;
};

/**
 * 注册新用户。
 * @param payload - 邮箱（可选），手机号（可选），密码。
 */
async function registerUser(payload: RegisterPayload): Promise<User | null> {
  isLoading.value = true;
  errorMessage.value = null;
  try {
    // Basic client-side validation
    if (!(payload.email || payload.phone_number) || !payload.password) {
      throw new Error('Email or phone number, and password are required.');
    }
    if (payload.email && !/\S+@\S+\.\S+/.test(payload.email)) {
        throw new Error('Invalid email format.');
    }

    const response = await axios.post<AuthResponse>(`${API_BASE_URL}/register`, payload);
    console.log('Registration successful:', response.data.message);
    if (response.data.user) {
      currentUser.value = response.data.user; // Optionally update current user state
      return response.data.user;
    }
    return null;
  } catch (error) {
    errorMessage.value = handleApiError(error, 'Registration failed.');
    console.error('Registration error:', errorMessage.value);
    return null;
  } finally {
    isLoading.value = false;
  }
}

/**
 * 使用标识符（邮箱/手机号）和密码登录用户。
 * @param payload - 标识符和密码。
 */
async function loginWithPassword(payload: LoginPasswordPayload): Promise<User | null> {
  isLoading.value = true;
  errorMessage.value = null;
  try {
    if (!payload.identifier || !payload.password) {
      throw new Error('Identifier and password are required.');
    }
    const response = await axios.post<AuthResponse>(`${API_BASE_URL}/login/password`, payload);
    console.log('Login successful:', response.data.message);
    if (response.data.user) {
      currentUser.value = response.data.user;
      return response.data.user;
    }
    return null;
  } catch (error) {
    errorMessage.value = handleApiError(error, 'Login failed.');
    console.error('Login error:', errorMessage.value);
    return null;
  } finally {
    isLoading.value = false;
  }
}

/**
 * 向用户的手机号发送OTP。
 * @param payload - 手机号。
 */
async function sendLoginOtp(payload: SendOtpPayload): Promise<boolean> {
  isLoading.value = true;
  errorMessage.value = null;
  try {
    if (!payload.phone_number) {
      throw new Error('Phone number is required.');
    }
    const response = await axios.post<AuthResponse>(`${API_BASE_URL}/login/phone/send-otp`, payload);
    console.log('Send OTP response:', response.data.message);
    return true;
  } catch (error) {
    errorMessage.value = handleApiError(error, 'Failed to send OTP.');
    console.error('Send OTP error:', errorMessage.value);
    return false;
  } finally {
    isLoading.value = false;
  }
}

/**
 * 验证OTP并登录用户。
 * @param payload - 手机号和OTP。
 */
async function verifyLoginOtp(payload: VerifyOtpPayload): Promise<User | null> {
  isLoading.value = true;
  errorMessage.value = null;
  try {
    if (!payload.phone_number || !payload.otp) {
      throw new Error('Phone number and OTP are required.');
    }
    const response = await axios.post<AuthResponse>(`${API_BASE_URL}/login/phone/verify-otp`, payload);
    console.log('OTP verification successful:', response.data.message);
    if (response.data.user) {
      currentUser.value = response.data.user;
      return response.data.user;
    }
    return null;
  } catch (error) {
    errorMessage.value = handleApiError(error, 'OTP verification failed.');
    console.error('OTP verification error:', errorMessage.value);
    return null;
  } finally {
    isLoading.value = false;
  }
}

/**
 * 注销当前用户。
 */
async function logoutUser(): Promise<boolean> {
  isLoading.value = true;
  errorMessage.value = null;
  try {
    const response = await axios.post<AuthResponse>(`${API_BASE_URL}/logout`);
    console.log('Logout successful:', response.data.message);
    currentUser.value = null;
    return true;
  } catch (error) {
    // Logout might fail if the session is already invalid or network issue
    // Forcing logout on client-side regardless of server error might be a strategy
    currentUser.value = null; // Clear user state on client even if server call fails
    errorMessage.value = handleApiError(error, 'Logout failed. You have been logged out locally.');
    console.error('Logout error:', errorMessage.value);
    return false; // Indicate server logout might have failed
  } finally {
    isLoading.value = false;
  }
}

/**
 * 获取当前认证用户的详细信息。
 */
async function fetchCurrentUser(): Promise<User | null> {
  isLoading.value = true;
  errorMessage.value = null;
  try {
    const response = await axios.get<{ user: User }>(`${API_BASE_URL}/me`);
    console.log('Fetched current user:', response.data.user);
    currentUser.value = response.data.user;
    return response.data.user;
  } catch (error) {
     // If /me returns 401 (Unauthorized), it means user is not logged in
    if (axios.isAxiosError(error) && error.response?.status === 401) {
        currentUser.value = null; // Ensure local state reflects not logged in
        errorMessage.value = '您尚未登录。';
    } else {
        errorMessage.value = handleApiError(error, '获取用户详情失败。');
    }
    console.error('Fetch current user error:', errorMessage.value);
    return null;
  } finally {
    isLoading.value = false;
  }
}

/**
 * 为给定的标识符（邮箱/手机号）请求密码重置。
 * @param payload - 标识符。
 */
async function requestPasswordReset(payload: ForgotPasswordRequestPayload): Promise<boolean> {
  isLoading.value = true;
  errorMessage.value = null;
  try {
    if (!payload.identifier) {
      throw new Error('Email or phone number is required.');
    }
    const response = await axios.post<AuthResponse>(`${API_BASE_URL}/password/forgot/request`, payload);
    console.log('Password reset request response:', response.data.message);
    // Usually, you don't get direct feedback if the user exists for security reasons
    // The message from backend "If your account exists..." is good.
    return true;
  } catch (error) {
    errorMessage.value = handleApiError(error, '密码重置请求失败。');
    console.error('Password reset request error:', errorMessage.value);
    return false;
  } finally {
    isLoading.value = false;
  }
}

/**
 * 使用Token重置密码。
 * @param payload - Token和新密码。
 */
async function resetPasswordWithToken(payload: ResetPasswordTokenPayload): Promise<boolean> {
  isLoading.value = true;
  errorMessage.value = null;
  try {
    if (!payload.token || !payload.new_password) {
      throw new Error('Token and new password are required.');
    }
    const response = await axios.post<AuthResponse>(`${API_BASE_URL}/password/reset/token`, payload);
    console.log('Password reset successful:', response.data.message);
    return true;
  } catch (error) {
    errorMessage.value = handleApiError(error, '密码重置失败。');
    console.error('Password reset error:', errorMessage.value);
    return false;
  } finally {
    isLoading.value = false;
  }
}

export {
  registerUser,
  loginWithPassword,
  sendLoginOtp,
  verifyLoginOtp,
  logoutUser,
  fetchCurrentUser,
  requestPasswordReset,
  resetPasswordWithToken,
  currentUser,
  isLoading,
  errorMessage
};